package com.hdg.boot.service.impl;

import com.hdg.boot.bo.NewAddTableBo;
import com.hdg.boot.bo.NewUpdateTableBo;
import com.hdg.boot.bo.XirMdBo;
import com.hdg.boot.dto.ExcelAddDownloadDto;
import com.hdg.boot.dto.ExcelUpdateDownloadDto;
import com.hdg.boot.mapper.NewAddTableMapper;
import com.hdg.boot.mapper.NewUpdateTableMapper;
import com.hdg.boot.mapper.XirMdMapper;
import com.hdg.boot.pojo.TableAndColumn;
import com.hdg.boot.service.DataCompareService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.thymeleaf.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class DataCompareServiceImpl implements DataCompareService {


    @Resource
    XirMdMapper xirMdMapper;
    @Resource
    NewAddTableMapper newAddTableMapper;
    @Resource
    NewUpdateTableMapper newUpdateTableMapper;


    @Override
    public List<ExcelUpdateDownloadDto> getUpdateData() {
        List<ExcelUpdateDownloadDto> list =  newUpdateTableMapper.getAll();
        return CollectionUtils.isEmpty(list)?new ArrayList<>():list;
    }

    @Override
    public List<ExcelAddDownloadDto> getAddData() {
        List<ExcelAddDownloadDto> list = newAddTableMapper.getAll();
        return CollectionUtils.isEmpty(list)?new ArrayList<>():list;
    }

    @Override
    @Transactional
    public void addXirMdsByName(List<XirMdBo> list, String tableName){
        if(CollectionUtils.isEmpty(list) || StringUtils.isEmpty(tableName)){
            return;
        }
        Set<String> addTableName = new HashSet<>();
        List<NewAddTableBo> addList = new ArrayList<>();
        List<NewUpdateTableBo> updateTable = new ArrayList<>();
        List<String> tableNameList = new ArrayList<>(new HashSet<>(list.stream().map(XirMdBo::getEnglishName).collect(Collectors.toList())));
        List<XirMdBo> dbList = xirMdMapper.getData(tableNameList,tableName);
        //标记查出来的所有表结构
        List<String> hadTables = new ArrayList<>(new HashSet<>(dbList.stream().map(XirMdBo::getEnglishName).collect(Collectors.toList())));
        //修改准生产一存在表的状态
        if(!CollectionUtils.isEmpty(hadTables)){
            xirMdMapper.updateHadTable(hadTables,tableName);
        }
        HashMap<String,List<XirMdBo>> dbMap = new HashMap<>();
        dbList.forEach(x->{
            if(dbMap.containsKey(x.getEnglishName())){
                dbMap.get(x.getEnglishName()).add(x);
            }else {
                List<XirMdBo> xirMdBos = new ArrayList<>();
                xirMdBos.add(x);
                dbMap.put(x.getEnglishName(),xirMdBos);
            }
        });
        //数据是否之前在新增表中出现过
        Integer num = newAddTableMapper.getData(list.get(0).getEnglishName());
        List<String> addTable = tableNameList.stream().filter(x -> !dbMap.containsKey(x)).collect(Collectors.toList());
        if(num > 0){
             addTable.remove(list.get(0).getEnglishName());
        }
        //准生产中已存在的表字段
        List<TableAndColumn> hadColumn = new ArrayList<>();
        list.forEach(x->{
            if(addTable.contains(x.getEnglishName()) && !addTableName.contains(x.getEnglishName())){//是新增表
                addTableName.add(x.getEnglishName());
                NewAddTableBo bo = new NewAddTableBo();
                bo.setEnglishName(x.getEnglishName());
                bo.setChineseName(x.getChineseName());
                bo.setOwner(x.getOwner());
                bo.setYn(1);
                addList.add(bo);
            }else if(!addTable.contains(x.getEnglishName())){//不是新增表
                //对比数据
                //boolean contains = dbMap.get(x.getEnglishName()).stream().map(XirMdBo::getColumnName).collect(Collectors.toList()).contains(x.getColumnName());
                List<XirMdBo> dbMapList= dbMap.get(x.getEnglishName());
                List<XirMdBo> collect = new ArrayList<>();
                if(!CollectionUtils.isEmpty(dbMapList)){
                    collect = dbMapList.stream().filter(z -> z.getColumnName().equals(x.getColumnName())).collect(Collectors.toList());
                }
                //是否使新增字段
                if(!CollectionUtils.isEmpty(collect)){//不是
                    //数据对比类封装
                    String dataCompare = dataCompare(collect.get(0), x);
                    if(!StringUtils.isEmpty(dataCompare)){//修改
                        NewUpdateTableBo bo = assembleData(x,2);
                        bo.setCompareResult(dataCompare);
                        updateTable.add(bo);
                    }
                    //将已存在的字段添加进list集合
                    TableAndColumn tableAndColumn = new TableAndColumn();
                    tableAndColumn.setTableName(x.getEnglishName());
                    tableAndColumn.setColumnName(x.getColumnName());
                    hadColumn.add(tableAndColumn);
                }else{//新增的
                    NewUpdateTableBo bo = assembleData(x,1);
                    updateTable.add(bo);
                }
            }
        });
        if(!CollectionUtils.isEmpty(hadColumn)){
            xirMdMapper.updateColumnStatus(hadColumn,tableName);
        }
        if(!CollectionUtils.isEmpty(addList)){
            newAddTableMapper.add(addList);
        }
        if(!CollectionUtils.isEmpty(updateTable)){
            newUpdateTableMapper.addUpdateTable(updateTable);
        }
    }

    @Override
    public void hadTableAndColumn(String tableName) {
        //查询数准生产环境咩有使用到的表
        List<NewAddTableBo> notUseTables = xirMdMapper.getNotUseTable(tableName);
        //添加至对比表中保存
        if(!CollectionUtils.isEmpty(notUseTables)){
            newAddTableMapper.add(notUseTables);
        }
        //查询准生产缓降比测速环境多的字段
        List<NewUpdateTableBo> notUseColumn = xirMdMapper.getNotUseColumn(tableName);
        if(!CollectionUtils.isEmpty(notUseTables)){
            if(notUseColumn!=null&&notUseColumn.size()>0)
            newUpdateTableMapper.addUpdateTable(notUseColumn);
        }
    }

    private String dataCompare(XirMdBo dbXirMdBo, XirMdBo xirMdBo){
        StringJoiner sj = new StringJoiner("；", "", "。");
        if(!dbXirMdBo.getColumnType().equals(xirMdBo.getColumnType())){
            sj.add(description(dbXirMdBo.getColumnType(),xirMdBo.getColumnType(),"字段数据类型"));
        }
        if(!dbXirMdBo.getColumnLength().equals(xirMdBo.getColumnLength())){
            sj.add(description(dbXirMdBo.getColumnLength(),xirMdBo.getColumnLength(),"字段长度"));
        }
        if(dbXirMdBo.getScaleLength() != null && !dbXirMdBo.getScaleLength().equals(xirMdBo.getScaleLength())){
            sj.add(description(dbXirMdBo.getScaleLength(),xirMdBo.getScaleLength(),"字段小数长度"));
        }
        if(!dbXirMdBo.getIsEmpty().equals(xirMdBo.getIsEmpty())){
            sj.add(description(dbXirMdBo.getIsEmpty(),xirMdBo.getIsEmpty(),"是否可为空"));
        }
        if(!dbXirMdBo.getIsPrimaryKey().equals(xirMdBo.getIsPrimaryKey())){
            sj.add(description(dbXirMdBo.getIsPrimaryKey(),xirMdBo.getIsPrimaryKey(),"是否可为主键"));
        }
        if(sj.toString().equals("。")){
            return "";
        }
        return sj.toString();
    }


    private String description(String produce,String test,String columnType){
        return "测试环境" + columnType + "数据为：" + produce + "，准生产环境" + columnType + "数据为："  + test;
    }


    private NewUpdateTableBo assembleData(XirMdBo xirMdBo,Integer yn){
        NewUpdateTableBo bo = new NewUpdateTableBo();
        BeanUtils.copyProperties(xirMdBo, bo);
        bo.setYn(yn);
        return  bo;
    }
}
